/* 작성자 : Jint
 * 작성일 : 140508
 * 내용 :
 *  ProductMain 에서 쓰이는 사원 관리용 Thread 입니다.
 * 	이 Thread 에서는 출퇴근과 관련된 해쉬맵 3가지를 다룹니다.
 *  출퇴근 chul, 실시간출퇴근 chulG, 휴가관리 holy 의 세가지 해쉬맵입니다.
 *  모든 해쉬맵의 key 값은 사원번호이고, Value 값은 MemberData로 통일합니다.
 *  
 *  ProductMain 프로그램이 실행됨과 동시에 스레드가 작동하며, 작동되는 순간
 *  현재까지 저장된 BackUp Data를 불러오게 됩니다.
 *  이때 백업데이터에 저장된 날짜가 오늘의 날짜와 맞지않으면 
 *  1.데이터를 지우게 됩니다. or 2.오늘 해쉬맵으로 저장 or 3.새로운 날짜의 데이터생성.
 *  
 *  불러온 데이터의 날짜가 오늘이면 ProductMain 의 chulG 해쉬맵에 백업데이터를 저장해줍니다.
 *  
 *  
 *  Thread에서 하는 역할은 실시간 출퇴근 chulG의 사이즈를 매순간 측정하여 사이즈가 증가되었을시
 *  chulG 해쉬맵을 파일로 저장하여 데이터백업을 하도록합니다.
 *  기존 chulG 해쉬맵의 사이즈를 저장해놓을 temp가 있어야, 현재의 사이즈와 비교.
 *  
 *  
 *  출퇴근 chul 해쉬맵에 저장되는 logic
 *  1. 오후 5시가 되었을때, 출근한 사람은 자동으로 퇴근처리가 되도록 도와주고
 *  2. 출근하지 않은 사람중, 휴가를 쓴 사람은 휴가처리가 되도록 처리해주고,
 *   휴가가 사용되었을때, 해당 휴가 항목은 휴가 해쉬맵에서 삭제되도록 합니다.
 *  3. 출근하지 않은 사람중, 휴가도 사용하지 않았다면 무단 결근처리가 되도록 합니다.
 *  4. 모든 과정이 끝나면 해당 날짜의 chul 해쉬맵을 파일로 백업하여 줍니다.
 *  
 * 	
 */


package product;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;



public class MemberThread extends Thread{

	ProductMain pm;
	MemberData md;
	
	
	boolean tFlag=true;
	boolean fExist=false;
	boolean finish=false;
	boolean chulCheck=false;
	int oldSize;

	Date timeCheck;
	Date today = new Date();
	SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); // file 저장용
	SimpleDateFormat timeC = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
	SimpleDateFormat checkToday = new SimpleDateFormat("yy-MM-dd");

	//데이터를 백업하기위한
	ObjectOutputStream send;
	ObjectInputStream receive;
	FileOutputStream fos;
	FileInputStream fis;	
	File f;

	// ProductMain에 있는 해쉬맵에 접근하기 위하여 생성될때 매개변수로 ProductMain 을 받아옵니다.
	public MemberThread(ProductMain p) {
		this.pm=p;
		

		//오늘 날짜의 데이터가 있는지 없는지 검색
		//없으면, chulG에 관리자 출석을 입력하고, 오늘 날짜의 chulG 데이터를 생성
		//있으면 불러와서 chulG에 저장.


		//C:\memCheck -> 저장될 폴더.
		f = new File("/MemberManage/");
		// 만약 폴더가 없으면, 생성한다.
		if(!f.exists()){
			f.mkdir();
		}
		//폴더 내부에 있는 파일 목록을 읽어들인다.
		String[] list = f.list();

		//오늘 날짜의 파일이 있는지 여부 검사.
		for(int i=0;i<list.length;i++){
			if(list[i].contains(sdf.format(today))){
				fExist=true;
			}
		}

		//파일이 없으면 새로 생성하고, 파일이 있으면 파일을 읽어들여 해쉬맵에 저장해준다.
		try {
			if(fExist){

				receive = new ObjectInputStream(new FileInputStream("/MemberManage/" + sdf.format(today) + ".date"));
//				pm.chulG = (LinkedHashMap<String, ChulGData>)receive.readObject();
//				receive.close();

			}else{

				send = new ObjectOutputStream(new FileOutputStream("/MemberManage/" + sdf.format(today) + ".date"));				
//				send.writeObject(pm.chulG);
//				send.close();				

			}
		} catch (FileNotFoundException e) {				
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
//		catch (ClassNotFoundException e) {
//			e.printStackTrace();
//		}

		//스레드가 생성되면서 chulG의 size를 받아옵니다.
		oldSize = pm.chulG.size();


		//스레드 시작
		this.start();



	}

	public void run(){
		String tem=sdf.format(today);
		
		while(tFlag){
//			chulG에 데이터가 추가 될 때마다, 백업파일을 생성합니다.
			if(oldSize < pm.chulG.size()){

				try {
					send = new ObjectOutputStream(new FileOutputStream("/MemberManage/" + sdf.format(today) + ".date"));
					send.writeObject(pm.chulG);
					send.close();
					oldSize++;
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				

			}


			String now = timeC.format(new Date()); //시간 비교용
			String out = sdf.format(today) + " 17:00:00";
			
			
			//오후 5시가 되면 chulG -> chul 로 데이터를 구분합니다.
			//Thu May 08 12:38:40 KST 2014
			//20140508 12:38:40
			
			if(now.equals(out)){ //now.equals(out)
				System.out.println("저장!");
				
				//사원정보가 저장된 mem HashMap의 키값.
				Set<String> memCodeKey = pm.mem.keySet();
				Iterator<String> memKey = memCodeKey.iterator();
				
				//chulG에 들어있는 Key와 비교하기위한 SimpleDateFormat
				SimpleDateFormat findKey = new SimpleDateFormat("yyyy-MM-dd");
				String fk = findKey.format(new Date());
				
				
				//사원 Code를 while문으로 검색하면서, 검색조건(chulG Key)에 맞는 데이터는 LinkedList로 추려내어 
				//일일 출결현황을 알아내고, 이를 이용해 chul HashMap에 저장한다.
				while(memKey.hasNext()){
					//개인별 일일 출석현황 저장용 LinkedList
					LinkedList<String> aloneCheck = new LinkedList<String>();					
					
					//chulG에 있는 키셋을 받아와 비교한다.
					Iterator<String> chulGKey = pm.chulG.keySet().iterator();
					
					String memHMKey = memKey.next();
					//사원중에 chulG해당일에 출석/퇴근이 찍혀있다면 LinkedList에 목록을 저장한다. 
					while(chulGKey.hasNext()){
						String chulGHMKey = chulGKey.next();
						if(chulGHMKey.contains(("["+memHMKey+"]" + fk))){							
							aloneCheck.push(chulGHMKey+pm.chulG.get(chulGHMKey).getValueChul()); //[A1]2014-05-09 03: 18: 25출근   -> 이런형식으로 저장됨.						
						}
					}
					
					
					
					//우선 모든 멤버의 chul 값 초기화.
					//이름,코드,직책,부서,비밀번호,출석여부,휴가여부,일급여,입사일,해당날짜
					//public TempData(String name, String code, String level, String team, String password, int check, int leave, int pay, String joinDay, String today)
					TempData tdInit = new TempData(
							pm.mem.get(memHMKey).getIrum(), 
							pm.mem.get(memHMKey).getCode(),
							pm.mem.get(memHMKey).getPosition(),
							pm.mem.get(memHMKey).getTeam(),
							pm.mem.get(memHMKey).getPwd(),
							0,
							0, 
							pm.mem.get(memHMKey).getdPay(),
							pm.mem.get(memHMKey).getjDate(),
							checkToday.format(today)
							);
					
					pm.chul.put("["+memHMKey+"]"+sdf.format(today), tdInit);
					
					Iterator<String> holyKey = pm.holy.keySet().iterator();
					
					
					//ChulG 
					for(int i = 0; i<aloneCheck.size();i++){
						if(aloneCheck.get(i).contains(memHMKey)){
							chulCheck = true;
						}
					}
					
					
					//출석, 퇴근이 하나도 없는 경우.
					if(!chulCheck){	
						//해당 사원이 휴가를 신청했는지 여부를 가리기위해 holy HashMap 검색
						while(holyKey.hasNext()){						
							String holyHMKey = holyKey.next();
							//해당 사원이 휴가를 신청했을 경우.
							if(holyHMKey.equals("["+memHMKey+"]"+sdf.format(today))){
							
								
								System.out.println("Test!!!!");
								//chul 해쉬맵에 휴가정보를 등록해준다.
								//이름,코드,직책,부서,비밀번호,출석여부,휴가여부,일급여,입사일,해당날짜
								//public TempData(String name, String code, String level, String team, String password, int check, int leave, int pay, String joinDay, String today)			
								
								TempData td = new TempData(pm.mem.get(memHMKey).getIrum(), pm.mem.get(memHMKey).getCode(),
										pm.mem.get(memHMKey).getPosition(), pm.mem.get(memHMKey).getTeam(),
										pm.mem.get(memHMKey).getPwd(), 0,
										Integer.parseInt(pm.holy.get(holyHMKey).getYholy()),
										pm.mem.get(memHMKey).getdPay(),
										pm.mem.get(memHMKey).getjDate(),checkToday.format(today));
								
								pm.chul.put("["+memHMKey+"]"+tem, td);								
							}
						}
						
						//위에서 출석여부와, 휴가여부를 모두 0으로 초기화 해주었기때문에, 휴가를 신청하지 않은 경우는따로 저장하지 않아도 된다.
						
					}else if(chulCheck){ 
						// 출,퇴 기록이 있는 경우
						// chul 에 출석여부에 1을 담아 저장한다.
						
						TempData inoutCheck = new TempData(pm.mem.get(memHMKey).getIrum(), pm.mem.get(memHMKey).getCode(),
								pm.mem.get(memHMKey).getPosition(), pm.mem.get(memHMKey).getTeam(),
								pm.mem.get(memHMKey).getPwd(), 1,
								0, pm.mem.get(memHMKey).getdPay(),
								pm.mem.get(memHMKey).getjDate(),checkToday.format(today));
						
						
						pm.chul.put("["+memHMKey+"]"+tem, inoutCheck);
						chulCheck=false;
					}				
					
				}
				//해당 날짜 출석 저장이 종료 되었으므로 플래그를 올려주고, 
				//밑에 if문으로 file로 chul을 저장하고 플래그를 false로 바꿔준다.
				finish=true;
				
			}

			
			//chul 해쉬맵 데이터를 파일로 저장하여, 해당 날짜의 출석을 백업한다.
			if(finish){
				
				System.out.println("==================chul Data==========================");
				
				for(int i=1;i<6;i++){
					System.out.println("이름 : "+pm.chul.get("[A"+i+"]"+tem).getName());
					System.out.println("출석여부 : "+pm.chul.get("[A"+i+"]"+tem).getCheck());
					System.out.println("휴가여부 : "+pm.chul.get("[A"+i+"]"+tem).getLeave());
					System.out.println("직급 : "+pm.chul.get("[A"+i+"]"+tem).getLevel());
					System.out.println("사원번호 : "+pm.chul.get("[A"+i+"]"+tem).getIndex());
					System.out.println("입사일 : "+pm.chul.get("[A"+i+"]"+tem).getStart_date());
					System.out.println("비밀번호 : "+pm.chul.get("[A"+i+"]"+tem).getPassword());
					System.out.println("부서 : "+pm.chul.get("[A"+i+"]"+tem).getTeam());
					System.out.println("일 급여 : "+pm.chul.get("[A"+i+"]"+tem).getPay());
					System.out.println("출석날짜 : "+pm.chul.get("[A"+i+"]"+tem).getToday());
					System.out.println("==========================================");
				}
				
				
				
				
				
				//저장된 사원 정보 해쉬맵을 파일로 백업.				
				//폴더가 없으면 생성한다.
				File dirCheck = new File("/MemberManage/");
				if(!dirCheck.exists()){
					dirCheck.mkdir();
				}
				try {
					send = new ObjectOutputStream(new FileOutputStream("/MemberManage/ChulCheck")); // ChulCheck 파일로 저장.
					send.writeObject(pm.chul);
					send.close();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}					
				
				finish=false;
				
			}
			
			



		}

	}
}

